﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using log4net;
using log4net.Config;
using Microsoft.Practices.Prism.Events;
using Reactor.Customization;
using Reactor.Environment;
using Reactor.MiniManager.State;
using Reactor.Providers;
using Reactor.ServiceGrid.Repositories;

namespace Reactor.MiniManager
{
    public class Bootstrapper
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof (Bootstrapper));
        private const string LoggingConfigFile = "logConfig.xml";

        public void Go()
        {
            ConfigureLogging();

            // Allow an oppurtunity to customize initialization.
            // For all this client, the machine name and application name is used for the primary input queue on the service bus.
            InitializationCustomizationManager.PrimaryEndpointName = string.Format("Reactor.Client.{0}", System.Environment.MachineName);
            var customizationManager = new InitializationCustomizationManager();
            if (Log.IsDebugEnabled) Log.DebugFormat("There were {0} initialization customizers found", customizationManager.Customizers.Count);
            customizationManager.RunAll();
            Log.Info("Initialization customization complete.");

            // Instruct handler registry to discover handlers and initialize subscriptions.
            Context.ServiceBus.Configuration.MessageHandlerRegistry.ScanAssembliesForHandlers();
            Context.ServiceBus.Start();

            // Create event aggregator
            var eventAggregator = new EventAggregator();
            Context.ServiceLocator.RegisterInstance<IEventAggregator>(eventAggregator);

            // Create core state cache instance
            var coreDataProvider = Context.ServiceLocator.GetInstance<ICoreDataProvider>();
            var coreStateCache = new CoreStateCache(coreDataProvider, eventAggregator);
            Context.ServiceLocator.RegisterInstance<ICoreStateCache>(coreStateCache);

            // Create a service package repository instance
            // Currently, the MiniManager tool only supports running against SqlPackageRepository instances
            var connectionData = Context.ServiceLocator.GetInstance<PlatformConnectionData>();
            var packageRepository = PackageRepositoryFactory.Default.CreateRepository(connectionData.PackageRepositoryLocation);
            Context.GridContext.ServicePackageRepository = packageRepository;

            coreStateCache.Initialize();
        }

        private static void ConfigureLogging()
        {
            var logCustomizationManager = new LogCustomizationManager();
            if (Log.IsDebugEnabled) Log.DebugFormat("There were {0} log customizers found", logCustomizationManager.Customizers.Count);

            if (logCustomizationManager.Customizers.Any())
                logCustomizationManager.RunAll();
            else
            {
                // No log customizers found, so look for xml log configuration
                if (File.Exists(LoggingConfigFile))
                    XmlConfigurator.ConfigureAndWatch(new FileInfo(LoggingConfigFile));
            }

            Log.Info("Logging configuration complete.");
        }
    }
}
